/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_mac.h"
// #include "esp_err.h"
#include "esp_flash.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "mqtt_cjson_handle.h"
#include "main.h"
#include "generic_gpio.h"
#include "station.h"
#include "uart_events.h"
#include "gatt_server.h"
#include "mqtt_event.h"
#include "radar.h"
#include "nvs_value.h"
#include "lamp_ctrl.h"
#include "time_sntp.h"
#include "nvs_value.h"
#include "touch_board.h"
#include "Analog_IIC.h"
#include "ws2812.h"
#include "h03_config.h"

static const char *TAG = "[H03]";

user_attr_t user_attr;
event_flag_t event_flag;

static uint8_t mqtt_heartbeat_count;

static uint8_t study_time_count = 0;
static uint8_t studytime_save_count = 0;

// uint8_t tomato_mode;
static uint16_t inseat_count;
static uint16_t concentration_high_count;
timer_count_t timer_count;
bool system_restore_flag = 0;

bool bt_disconnect_flag = 0;
static bool ble_stop_flag = 0;
static void second_timer_callback(void* arg)
{
    static bool change = 0;
#ifdef  TASKLIST
    static uint8_t tasklist_count;
    tasklist_count++;
    if(tasklist_count == 10){
        tasklist_count = 0;
        task_list_flag = 1;

    }
#endif    
    static uint16_t sit_askance_count;
    static uint16_t concentration_low_count;
    if(system_state.main == NORMAL){
        mqtt_heartbeat_count++;
        if(mqtt_heartbeat_count >= 30){
            event_flag.mqtt_heartbeat = 1;
        }
    }
    if(lamp.tomato_mode == 1){
        timer_count.led_tomato_clock++;
        if(timer_count.led_tomato_clock == 1500 ||
            timer_count.led_tomato_clock == 3300 ||
            timer_count.led_tomato_clock == 5100 ||
            timer_count.led_tomato_clock == 6900){
            event_flag.led_tomato_clock = 1;
        }else if(timer_count.led_tomato_clock == 1800 ||
                timer_count.led_tomato_clock == 3600 ||
                timer_count.led_tomato_clock == 5400 ||
                timer_count.led_tomato_clock == 8100){
            event_flag.led_tomato_clock = 2;
            if(timer_count.led_tomato_clock == 8100){
                timer_count.led_tomato_clock = 0;
            }
        }
    }
    if(system_state.time_sync == 1){
        if(timer_count.nextday_leave > 0){
            timer_count.nextday_leave--;
            // printf("timer_count.gesture_detect:%d\n,", timer_count.gesture_detect);
            if(timer_count.nextday_leave <= 3600 && user_attr.gesture_mode == 1 && timer_count.gesture_detect == 0){
                user_attr.gesture_mode = 0;
                top_led_mode = 0;
            }else if(timer_count.nextday_leave == 61200 && user_attr.gesture_mode == 0){
                user_attr.gesture_mode = 1;
                top_led_mode = 2;
            }
            // printf("gesture_mode:%d\n,", user_attr.gesture_mode);
        }else if(timer_count.nextday_leave == 0 && human_state.body_status == 0){
            timer_count.nextday_leave = 86400;
            event_flag.time_sync = 1;
        }        
    }
    if(system_state.main >= 4){
        timer_count.radar_err_count++;
    }
    study_time_count++;
    if(study_time_count >= 60){
        study_time_count = 0;
        event_flag.study_time_calculated = 1;
    }
    if(timer_count.rst_delay > 0){
        timer_count.rst_delay--;
        if(timer_count.rst_delay == 0){
            esp_restart();
        }
    }
    if(key_now == 1 && system_restore_flag == 0){
        key1_count++;
        if(key1_count == 10){
            key1_count = 0;
            event_flag.reset_key = 1;
        }
    }
    if(system_state.main == SMARTCONFIG){
        change = !change;
        key1_indicator_updata(change);
    }
    if(human_state.present_state == 1){
        timer_count.present_state_count++;
        if(timer_count.present_state_count >= 10){
            timer_count.present_state_count = 0;
            human_state.present_state = 2;
            event_flag.led_break = 1;
        }
    }
    if(human_state.present_state == 3){
        timer_count.present_state_count++;
    }
    if(timer_count.gesture_detect > 0){
        timer_count.gesture_detect--;
        if(timer_count.gesture_detect == 0){
            event_flag.gesture = 1;
        }else if(timer_count.gesture_detect == 10){
            event_flag.led_break = 1;
        }
    }
    if(event_flag.key_password == 1){
        timer_count.key_password--;
        if(timer_count.key_password == 0){
            event_flag.key_password = 0;
        }
    }
    if(inseat_state == 1){
        inseat_count++;
        if(inseat_count == 60){
            event_flag.warning_event = 1;
        }else if(inseat_count == 3660){
            event_flag.warning_event = 4;
        }
    }else if(inseat_count > 0){
        inseat_count = 0;
    }
    if(human_state.flow_state > 0 && human_state.flow_state < 5){
        if(concentration_low_count != 300){
            concentration_low_count++;
            if(concentration_low_count == 300){
                event_flag.warning_event = 2;
            }
        }
    }else if(concentration_low_count > 0){
        concentration_low_count = 0;
    }
    if(human_state.flow_state_level == 10){
        if(concentration_high_count != 300){
            concentration_high_count++;
            if(concentration_high_count == 300){
                event_flag.warning_event = 3;
            }
        }
    }else if(concentration_high_count > 0){
        concentration_high_count = 0;
    }
    if(timer_count.comeandgo_count < 300){
        timer_count.comeandgo_count++;
    }
    if((human_state.position_interval > 7 || human_state.position_interval < 4)&& human_state.position_interval != 0){
        sit_askance_count++;
        if(sit_askance_count == 300){
            event_flag.warning_event = 6;
        }
    }else if(sit_askance_count > 0){
        sit_askance_count = 0;
    }
    if(timer_count.ble_stop > 0){
        timer_count.ble_stop--;
        if(timer_count.ble_stop == 0){
            ble_stop_flag = 1;
        }
    }
    if(user_attr.sending_mode == 2){
        if(timer_count.human_attr > 0){
            timer_count.human_attr--;
            if(timer_count.human_attr == 0){
                event_flag.human_attr = 1;
            }
        }
    }
    // ESP_LOGI(TAG, "free heap size: %" PRIu32 " bytes", esp_get_free_heap_size());
}

void user_timer_init(void)
{
    const esp_timer_create_args_t second_timer_args = {
        .callback = &second_timer_callback,
        .name = "periodic"
    };

    esp_timer_handle_t second_timer;
    ESP_ERROR_CHECK(esp_timer_create(&second_timer_args, &second_timer));

    /* Start the timers */
    ESP_ERROR_CHECK(esp_timer_start_periodic(second_timer, 1000000));
}

#ifdef  TASKLIST
static void print_task_list(void)
{
    // 创建一个用于存储任务列表的缓冲区
    char *buffer = malloc(1024);
    if (buffer == NULL) {
        ESP_LOGE("TaskList", "Failed to allocate buffer for task list");
        return;
    }
 
    // 获取任务列表
    vTaskList((char *)buffer);
 
    // 打印任务列表
    ESP_LOGI("TaskList", "Task List:\n%s", buffer);
 
    // 释放缓冲区
    free(buffer);
}
#endif

static void network_event_manage_task(void *parm)
{
    initialise_wifi();
    uint8_t set_wifi = station(!device_attr.initial);
    if(set_wifi == true){
        gatt_server();
        ble_update_device_info();
        smartconfig();
    }
    if(system_state.wifi != wifi_SUCCESS){
        xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT,
                            true, false, portMAX_DELAY);
    }
    mqtt_task();
    for(uint8_t i=0; i<5; i++){
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        if(system_state.time_sync == 1) break;
    }
    sntp_start();

    vTaskDelete(NULL);
}

void study_time_calculated(learning_duration_t *duration)
{
    if(human_state.flow_state >= 80 && human_state.flow_state != 255){
        duration->severe++;                
    }else if(human_state.flow_state >= 50){
        duration->moderate++;
    }else if(human_state.flow_state > 0){
        duration->mild++;
    }
    if(human_state.body_status == 1 && system_state.main > 4){
        duration->present++;
    }
    if(lamp.onoff_status == 1){
        learning_duration.lighting++;
    }
     ESP_LOGI(TAG, "learning time update, %d, %d, %d, %d, %d, %d", 
        duration->mild,
        duration->moderate,
        duration->severe,
        duration->present,
        duration->now,
        duration->sum);
}

static void user_event_manage_task(void *parm)
{ 
    while(1){
        if(system_state.main > SELF_TEST){
            if(system_state.main > 4){
            }
            if(event_flag.study_time_calculated == 1){
                event_flag.study_time_calculated = 0;
                study_time_calculated(&learning_duration);
                studytime_save_count++;
                if(studytime_save_count >= 15){
                    studytime_save_count = 0;
                    nvs_save_studytime(learning_duration);
                }
                event_flag.study_time = 1;
            }

            if(event_flag.led_tomato_clock == 1){
                event_flag.led_tomato_clock = 0;
                lamp_set_fade(0, lamp.color_temp, 1000);
            }else if(event_flag.led_tomato_clock == 2){
                event_flag.led_tomato_clock = 0;
                lamp_set_fade(lamp.brightness_val, lamp.color_temp, 1000);
            }
            if(human_state.present_state == 3){
                if(lamp.onoff_status == 1){
                    if(timer_count.present_state_count >= (lamp.delay_time*1)){
                        timer_count.present_state_count = 0;
                        human_state.present_state = 0;
                        event_flag.led_break = 1;
                        if(lamp.delay_time != 0){
                            lamp.onoff_status = 0;
                            lamp_updata(lamp.onoff_status, lamp.brightness_val, lamp.color_temp);
                        }
                    }
                }else{
                    timer_count.present_state_count = 0;
                    human_state.present_state = 0;
                    event_flag.led_break = 1;
                    ESP_LOGI(TAG, "present_state: %d", human_state.present_state);
                }
                            
            }
            if(event_flag.reset_key == 1){
                ESP_LOGI(TAG,"long button!");
                event_flag.reset_key = 0;
                paramenter_restore(2);
                ESP_LOGI(TAG,"smartconfig setting ok, now reset!");
                ET6226M_display_all();
                restart_os();
            }
            if(ble_stop_flag == 1){
                ble_stop_flag = 0;
                gatt_bt_disconnect();
            }
            if(system_state.main == NORMAL){
                if(event_flag.mqtt_heartbeat == 1){
                    event_flag.mqtt_heartbeat = 0;
                    mqtt_heartbeat_count = 0;
                    cJSON_creat_heartbeat();
                }else if(event_flag.time_sync == 1){
                    event_flag.time_sync = 0;
                    cJSON_creat_sync();
                }else if(event_flag.all_attr == 1){
                    event_flag.all_attr = 0;
                    cJSON_creat_attr("all", 0);
                }else if(event_flag.human_attr == 1){
                    event_flag.human_attr = 0;
                    timer_count.human_attr = user_attr.sending_period;
                    cJSON_creat_attr("human_attr", 0);
                }else if(event_flag.body_status == 1){
                    event_flag.body_status = 0;
                    cJSON_creat_event("body_status", human_state.body_status);
                }else if(event_flag.posture_state == 1){
                    event_flag.posture_state = 0;
                    cJSON_creat_event("posture_state", human_state.posture_state);
                }else if(event_flag.activity_freq == 1){
                    event_flag.activity_freq = 0;
                    cJSON_creat_event("activity_freq", human_state.activity_freq);
                }else if(event_flag.warning_event != 0){
                    cJSON_creat_event("warning_event", event_flag.warning_event);
                    event_flag.warning_event = 0;                    
                }else if(event_flag.respiratory == 1){
                    event_flag.respiratory = 0;
                    cJSON_creat_attr("respiratory", human_state.respiratory);
                }else if(event_flag.heart_rate == 1){
                    event_flag.heart_rate = 0;
                    cJSON_creat_attr("heart_rate", human_state.heart_rate);
                }else if(event_flag.body_movement == 1){
                    event_flag.body_movement = 0;
                    cJSON_creat_attr("body_movement", human_state.body_movement);
                }else if(event_flag.body_angle == 1){
                    event_flag.body_angle = 0;
                    cJSON_creat_attr("body_angle", human_state.body_angle);
                }else if(event_flag.body_distance == 1){
                    event_flag.body_distance = 0;
                    cJSON_creat_attr("body_distance",  human_state.body_distance);
                }else if(event_flag.flow_state == 1){
                    event_flag.flow_state = 0;
                    cJSON_creat_attr("flow_state", human_state.flow_state_level);  
                }else if(event_flag.position_interval == 1){
                    event_flag.position_interval = 0;
                    cJSON_creat_attr("position_interval", human_state.position_interval);
                }else if(event_flag.study_time == 1){
                    event_flag.study_time = 0;
                    cJSON_creat_attr("study_time", 0);
                }else if(event_flag.radar_error == 1){
                    event_flag.radar_error = 0;
                    cJSON_creat_error(501);
                }
            }
            // if(event_flag.gesture == 1){
            //     event_flag.gesture = 0;
            //     event_flag.led_break = 1;
            //     uint8_t mode = 0x04; 
            //     radar_write_crc(0x02, 0x02, 0x11, (uint8_t *)&mode, sizeof(mode));
            // }
        }
        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

void user_event_init(void)
{
    xTaskCreate(network_event_manage_task, "network_event_manage_task", 1024*3, NULL, 10, NULL);
    xTaskCreate(user_event_manage_task, "user_event_manage_task", 1024*4, NULL, 15, NULL);
}